Question: “How can I use vector data from Open Street Map?”

Objectives:

  • Explain how OpenStreetMap (OSM) geodata works
  • Demonstrate how to import, select, and visualise OSM vector data

library(dplyr)
library(sf)
library(ggplot2)
library(remotes)
remotes::install_github('ropensci/osmdata')
library(osmdata)
library(osmextract)

Import vector data from Open Street Map

What is Open Street Map?

Open Street Map (OSM) is a collaborative project which aims at mapping the world and sharing geospatial data in an open way. Anyone can contribute, by mapping geographical objects their encounter, by adding topical information on existing map objects (their name, function, capacity, etc.), or by mapping buildings and roads from satellite imagery (cf. HOT: Humanitarian OpenStreetMap Team).

This information is then validated by other users and eventually added to the common “map” or information system. This ensures that the information is accessible, open, verified, accurate and up-to-date.

The result looks like this: View of OSM web interface The geospatial data underlying this interface is made of geometrical objects (i.e. points, lines, polygons) and their associated tags (#building #height, #road #secondary #90kph, etc.).

How to extract geospatial data from Open Street Map?

Bonding-box

The first thing to do is to define the area within which you want to retrieve data, aka the bounding box. This can be defined easily using a place name and the function getbb() from the package osmdata.

“This function uses the free Nominatim API provided by OpenStreetMap to find the bounding box (bb) associated with place names.”

assign("has_internet_via_proxy", TRUE, environment(curl::has_internet))

bb <- getbb('Delft', format_out = 'sf_polygon')

bb
Simple feature collection with 3 features and 0 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: 4.320218 ymin: 9.474415 xmax: 79.73152 ymax: 52.0326
Geodetic CRS:  WGS 84
                        geometry
1 POLYGON ((4.320218 52.00807...
2 POLYGON ((4.320218 52.00807...
3 POLYGON ((79.65064 9.541313...
  • Why multiple polygons?

Because there are different responses from the API query, corresponding to different objects at the same location, or different objects are different locations.

Extracting features

A feature in the OSM language is a category or tag of a geospatial object. Features are described by general keys (e.g. “building”, “boundary”, “landuse”, “highway”), themselves decomposed into sub-categories (values) such as “farm”, “hotel” or “house” for buildings, “motorway”, “secondary” and “residential” for highway. This determines how they are represented on the map.

x <- opq(bbox = bb) %>% 
   add_osm_feature(key = 'building') %>%
    osmdata_sf ()

What is this x object made of? It is a table of all the buildings contained in the bounding box, which gives us their OSM id, their geometry and a range of attributes, such as their name, building material, building date, etc. The completion level of this table depends on user contributions and open resources (here for instance: BAG, different in other countries).

head(x$osm_polygons)
Simple feature collection with 6 features and 145 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: 4.371179 ymin: 51.99641 xmax: 4.39319 ymax: 52.006
Geodetic CRS:  WGS 84
           osm_id             name access addr.city addr.country addr.housename
7536962   7536962 Sporthal Emerald   <NA>  Delfgauw           NL           <NA>
32017871 32017871             <NA>   <NA>      <NA>         <NA>           <NA>
32017872 32017872             <NA>   <NA>      <NA>         <NA>           <NA>
32017873 32017873             <NA>   <NA>      <NA>         <NA>           <NA>
32045333 32045333        Cambridge   <NA>      <NA>         <NA>           <NA>
32045334 32045334           Oxford   <NA>      <NA>         <NA>           <NA>
         addr.housenumber addr.postcode   addr.street alt_name amenity
7536962                 1        2645HH Florijnstraat     <NA>    <NA>
32017871             <NA>          <NA>          <NA>     <NA>    <NA>
32017872             <NA>          <NA>          <NA>     <NA>    <NA>
32017873             <NA>          <NA>          <NA>     <NA>    <NA>
32045333             <NA>          <NA>          <NA>     <NA>    <NA>
32045334             <NA>          <NA>          <NA>     <NA>    <NA>
         antenna.type area barrier bicycle_parking bridge bridge.support
7536962          <NA> <NA>    <NA>            <NA>   <NA>           <NA>
32017871         <NA> <NA>    <NA>            <NA>   <NA>           <NA>
32017872         <NA> <NA>    <NA>            <NA>   <NA>           <NA>
32017873         <NA> <NA>    <NA>            <NA>   <NA>           <NA>
32045333         <NA> <NA>    <NA>            <NA>   <NA>           <NA>
32045334         <NA> <NA>    <NA>            <NA>   <NA>           <NA>
           building building.colour building.flats building.levels
7536962         yes            <NA>           <NA>            <NA>
32017871 apartments            <NA>           <NA>               6
32017872 apartments            <NA>           <NA>               6
32017873 apartments            <NA>           <NA>               6
32045333        yes            <NA>           <NA>               5
32045334 apartments            <NA>           <NA>               5
         building.levels.aboveground building.levels.underground
7536962                         <NA>                        <NA>
32017871                        <NA>                        <NA>
32017872                        <NA>                        <NA>
32017873                        <NA>                        <NA>
32045333                        <NA>                        <NA>
32045334                        <NA>                        <NA>
         building.material building.min_level building.part building.use
7536962               <NA>               <NA>          <NA>         <NA>
32017871             brick               <NA>          <NA>         <NA>
32017872             brick               <NA>          <NA>         <NA>
32017873             brick               <NA>          <NA>         <NA>
32045333              <NA>               <NA>          <NA>         <NA>
32045334              <NA>               <NA>          <NA>         <NA>
         capacity check_date check_date.existence club colour construction
7536962      <NA>       <NA>                 <NA> <NA>   <NA>         <NA>
32017871     <NA>       <NA>                 <NA> <NA>   <NA>         <NA>
32017872     <NA>       <NA>                 <NA> <NA>   <NA>         <NA>
32017873     <NA>       <NA>                 <NA> <NA>   <NA>         <NA>
32045333     <NA>       <NA>                 <NA> <NA>   <NA>         <NA>
32045334     <NA>       <NA>                 <NA> <NA>   <NA>         <NA>
         contact.phone content covered craft cuisine denomination description
7536962           <NA>    <NA>    <NA>  <NA>    <NA>         <NA>        <NA>
32017871          <NA>    <NA>    <NA>  <NA>    <NA>         <NA>        <NA>
32017872          <NA>    <NA>    <NA>  <NA>    <NA>         <NA>        <NA>
32017873          <NA>    <NA>    <NA>  <NA>    <NA>         <NA>        <NA>
32045333          <NA>    <NA>    <NA>  <NA>    <NA>         <NA>        <NA>
32045334          <NA>    <NA>    <NA>  <NA>    <NA>         <NA>        <NA>
         disused.amenity disused.building disused.building.colour disused.power
7536962             <NA>             <NA>                    <NA>          <NA>
32017871            <NA>             <NA>                    <NA>          <NA>
32017872            <NA>             <NA>                    <NA>          <NA>
32017873            <NA>             <NA>                    <NA>          <NA>
32045333            <NA>             <NA>                    <NA>          <NA>
32045334            <NA>             <NA>                    <NA>          <NA>
         disused.roof.colour drinking_water email emergency exit  fee fixme
7536962                 <NA>           <NA>  <NA>      <NA> <NA> <NA>  <NA>
32017871                <NA>           <NA>  <NA>      <NA> <NA> <NA>  <NA>
32017872                <NA>           <NA>  <NA>      <NA> <NA> <NA>  <NA>
32017873                <NA>           <NA>  <NA>      <NA> <NA> <NA>  <NA>
32045333                <NA>           <NA>  <NA>      <NA> <NA> <NA>  <NA>
32045334                <NA>           <NA>  <NA>      <NA> <NA> <NA>  <NA>
         generator.method generator.output.electricity generator.source
7536962              <NA>                         <NA>             <NA>
32017871             <NA>                         <NA>             <NA>
32017872             <NA>                         <NA>             <NA>
32017873             <NA>                         <NA>             <NA>
32045333             <NA>                         <NA>             <NA>
32045334             <NA>                         <NA>             <NA>
         generator.type healthcare height heritage heritage.operator highway
7536962            <NA>       <NA>   <NA>     <NA>              <NA>    <NA>
32017871           <NA>       <NA>   <NA>     <NA>              <NA>    <NA>
32017872           <NA>       <NA>   <NA>     <NA>              <NA>    <NA>
32017873           <NA>       <NA>   <NA>     <NA>              <NA>    <NA>
32045333           <NA>       <NA>     15     <NA>              <NA>    <NA>
32045334           <NA>       <NA>     15     <NA>              <NA>    <NA>
         historic image layer       leisure level level.usage levels  lit
7536962      <NA>  <NA>  <NA> sports_centre  <NA>        <NA>   <NA> <NA>
32017871     <NA>  <NA>  <NA>          <NA>  <NA>        <NA>   <NA> <NA>
32017872     <NA>  <NA>  <NA>          <NA>  <NA>        <NA>   <NA> <NA>
32017873     <NA>  <NA>  <NA>          <NA>  <NA>        <NA>   <NA> <NA>
32045333     <NA>  <NA>  <NA>          <NA>  <NA>        <NA>   <NA> <NA>
32045334     <NA>  <NA>  <NA>          <NA>  <NA>        <NA>   <NA> <NA>
         loc_name location man_made material min.height min_height museum
7536962      <NA>     <NA>     <NA>     <NA>       <NA>       <NA>   <NA>
32017871     <NA>     <NA>     <NA>     <NA>       <NA>       <NA>   <NA>
32017872     <NA>     <NA>     <NA>     <NA>       <NA>       <NA>   <NA>
32017873     <NA>     <NA>     <NA>     <NA>       <NA>       <NA>   <NA>
32045333     <NA>     <NA>     <NA>     <NA>       <NA>       <NA>   <NA>
32045334     <NA>     <NA>     <NA>     <NA>       <NA>       <NA>   <NA>
         museum_type name.en name.nl name.ru name.zh network note old_name
7536962         <NA>    <NA>    <NA>    <NA>    <NA>    <NA> <NA>     <NA>
32017871        <NA>    <NA>    <NA>    <NA>    <NA>    <NA> <NA>     <NA>
32017872        <NA>    <NA>    <NA>    <NA>    <NA>    <NA> <NA>     <NA>
32017873        <NA>    <NA>    <NA>    <NA>    <NA>    <NA> <NA>     <NA>
32045333        <NA>    <NA>    <NA>    <NA>    <NA>    <NA> <NA>     <NA>
32045334        <NA>    <NA>    <NA>    <NA>    <NA>    <NA> <NA>     <NA>
         old_name.wikidata opening_hours opening_hours.signed operator
7536962               <NA>          <NA>                 <NA>     <NA>
32017871              <NA>          <NA>                 <NA>     <NA>
32017872              <NA>          <NA>                 <NA>     <NA>
32017873              <NA>          <NA>                 <NA>     <NA>
32045333              <NA>          <NA>                 <NA>     <NA>
32045334              <NA>          <NA>                 <NA>     <NA>
         operator.type operator.wikidata operator.wikipedia outdoor_seating
7536962           <NA>              <NA>               <NA>            <NA>
32017871          <NA>              <NA>               <NA>            <NA>
32017872          <NA>              <NA>               <NA>            <NA>
32017873          <NA>              <NA>               <NA>            <NA>
32045333          <NA>              <NA>               <NA>            <NA>
32045334          <NA>              <NA>               <NA>            <NA>
         parking payment.cash payment.maestro phone power private
7536962     <NA>         <NA>            <NA>  <NA>  <NA>    <NA>
32017871    <NA>         <NA>            <NA>  <NA>  <NA>    <NA>
32017872    <NA>         <NA>            <NA>  <NA>  <NA>    <NA>
32017873    <NA>         <NA>            <NA>  <NA>  <NA>    <NA>
32045333    <NA>         <NA>            <NA>  <NA>  <NA>    <NA>
32045334    <NA>         <NA>            <NA>  <NA>  <NA>    <NA>
         pumping_station  ref          ref.bag ref.bag.old ref.heritage ref.rce
7536962             <NA> <NA> 1926100000497049        <NA>         <NA>    <NA>
32017871            <NA> <NA>  503100000024959        <NA>         <NA>    <NA>
32017872            <NA> <NA>  503100000024957        <NA>         <NA>    <NA>
32017873            <NA> <NA>  503100000024958        <NA>         <NA>    <NA>
32045333            <NA> <NA>  503100000030621        <NA>         <NA>    <NA>
32045334            <NA> <NA>  503100000030621        <NA>         <NA>    <NA>
         ref.tudelft religion removed.building roof.colour roof.direction
7536962         <NA>     <NA>             <NA>        <NA>           <NA>
32017871        <NA>     <NA>             <NA>        <NA>           <NA>
32017872        <NA>     <NA>             <NA>        <NA>           <NA>
32017873        <NA>     <NA>             <NA>        <NA>           <NA>
32045333        <NA>     <NA>             <NA>        <NA>           <NA>
32045334        <NA>     <NA>             <NA>        <NA>           <NA>
         roof.edge roof.height roof.levels roof.material roof.orientation
7536962       <NA>        <NA>        <NA>          <NA>             <NA>
32017871      <NA>        <NA>        <NA>          <NA>             <NA>
32017872      <NA>        <NA>        <NA>          <NA>             <NA>
32017873      <NA>        <NA>        <NA>          <NA>             <NA>
32045333      <NA>        <NA>        <NA>          <NA>             <NA>
32045334      <NA>        <NA>        <NA>          <NA>             <NA>
         roof.ridge roof.shape service_times shop short_name smoking
7536962        <NA>       <NA>          <NA> <NA>       <NA>    <NA>
32017871       <NA>       flat          <NA> <NA>       <NA>    <NA>
32017872       <NA>       flat          <NA> <NA>       <NA>    <NA>
32017873       <NA>       flat          <NA> <NA>       <NA>    <NA>
32045333       <NA>       <NA>          <NA> <NA>       <NA>    <NA>
32045334       <NA>       <NA>          <NA> <NA>       <NA>    <NA>
         social_facility.for source           source.date source.name
7536962                 <NA>    BAG 2013-09-01;2013-11-26        <NA>
32017871                <NA>    BAG            2013-11-26        <NA>
32017872                <NA>    BAG            2013-11-26        <NA>
32017873                <NA>    BAG            2013-11-26        <NA>
32045333                <NA>    BAG            2013-11-26        <NA>
32045334                <NA>    BAG            2013-11-26        <NA>
         source.old_name sport start_date street_cabinet substation surface
7536962             <NA>  <NA>       2001           <NA>       <NA>    <NA>
32017871            <NA>  <NA>       2008           <NA>       <NA>    <NA>
32017872            <NA>  <NA>       2008           <NA>       <NA>    <NA>
32017873            <NA>  <NA>       2008           <NA>       <NA>    <NA>
32045333            <NA>  <NA>       2007           <NA>       <NA>    <NA>
32045334            <NA>  <NA>       2007           <NA>       <NA>    <NA>
         survey.date toilets tourism tower.type type  url voltage
7536962         <NA>    <NA>    <NA>       <NA> <NA> <NA>    <NA>
32017871        <NA>    <NA>    <NA>       <NA> <NA> <NA>    <NA>
32017872        <NA>    <NA>    <NA>       <NA> <NA> <NA>    <NA>
32017873        <NA>    <NA>    <NA>       <NA> <NA> <NA>    <NA>
32045333        <NA>    <NA>    <NA>       <NA> <NA> <NA>    <NA>
32045334        <NA>    <NA>    <NA>       <NA> <NA> <NA>    <NA>
         watermill.disused website wheelchair wheelchair.description wikidata
7536962               <NA>    <NA>       <NA>                   <NA>     <NA>
32017871              <NA>    <NA>       <NA>                   <NA>     <NA>
32017872              <NA>    <NA>       <NA>                   <NA>     <NA>
32017873              <NA>    <NA>       <NA>                   <NA>     <NA>
32045333              <NA>    <NA>       <NA>                   <NA>     <NA>
32045334              <NA>    <NA>       <NA>                   <NA>     <NA>
         wikidata_1 wikipedia windmill.type windmill.vanes
7536962        <NA>      <NA>          <NA>           <NA>
32017871       <NA>      <NA>          <NA>           <NA>
32017872       <NA>      <NA>          <NA>           <NA>
32017873       <NA>      <NA>          <NA>           <NA>
32045333       <NA>      <NA>          <NA>           <NA>
32045334       <NA>      <NA>          <NA>           <NA>
                               geometry
7536962  POLYGON ((4.392537 52.00466...
32017871 POLYGON ((4.37131 51.99711,...
32017872 POLYGON ((4.371664 51.9966,...
32017873 POLYGON ((4.371552 51.99676...
32045333 POLYGON ((4.372431 52.00586...
32045334 POLYGON ((4.372391 52.00555...

Mapping attributes

For instance: the building age focusing on post-1900 buildings.

Projections

First, we are going to select the polygons and reproject them with the Amersfoort/RD New projection, suited for maps centred on the Netherlands.

buildings <- x$osm_polygons %>% st_transform(.,crs=28992)

Mapping

Then we create a variable which a threshold at 1900. Every date prior to 1900 will be recoded 1900, so that buildings older than 1900 will be represented with the same shade.

Then we use the ggplot function to visualise the buildings by age. The specific function to represent information as a map is geom_sf(). The rest works like other graphs and visualisation, with aes() for the aesthetics.

buildings$build_date <- as.numeric(ifelse(buildings$start_date <1900, 1900,buildings$start_date))

 ggplot(data = buildings) +
   geom_sf(aes(fill = build_date, colour=build_date))  +
   scale_fill_viridis_c(option = "viridis")+
   scale_colour_viridis_c(option = "viridis")

So this reveals the historical centre of Delft and the various extensions, the first ring in the 1920s, towards the South-West of the city (1970s-1990s), East of the city (2000s) and North-West (2010s). This centre-periphery and sectoral urban development is quite common. Now for a less typical example, can you reproduce this map for the city of Rotterdam. But instead of pre-XXth century building, we want to look at pre-war buildings. It will take some time to extract all buildings, so we will check the result after the coffee break.

Challenge: Map building age in Rotterdam, with 1945 as a threshold


Solution

Summary and keypoints

We have seen how OpenStreetMap (OSM) geodata works and how to import, select, and visualise OSM vector data.

In short: